import Ctx2 from '../../assets/js/ctx2'

export default class TurnGame {
  constructor(obj) {
    let config = {
      width: 300,
      height: 300,
      lightNum: 12,
      addNum: 1,
      arcMoveY: 0,
      prizeList: [],
      btnText: '开始抽奖',
      arcColorLine: '',
      arrowColor: 'rgb(255,0,0)',
      arcColorBig1: 'rgb(255, 151, 62)',
      arcColorBig2: 'rgb(255, 104, 64)',
      arcColorBig3: 'rgb(255, 168, 68)',
      arcColorBig4: 'rgb(254, 149, 68)',
      lightColorOn: 'rgb(245, 192, 88)',
      lightColorOff: 'rgb(255, 255, 255)',
      cPlayColor: 'rgb(255, 104, 64)',
    }
    Object.assign(config, obj)
    this.lightNum = config.lightNum
    this.prizeList = config.prizeList
    this.btnText = config.btnText
    this.addNum = config.addNum
    this.width = config.width
    this.height = config.width
    this.half = config.width / 2
    this.el = config.el
    this.vue = config.vue
    this.arrowColor = config.arrowColor
    this.cPlayImg = config.cPlayImg
    this.lightColorOn = config.lightColorOn
    this.lightColorOff = config.lightColorOff
    this.timer = null
    this.timer1 = {}
    this.timer2 = null
    this.lightFlag = false
    this.rotate1 = 0
    this.rotate2 = 0
    this.animateNum = 1
    this.arcColorBig1 = config.arcColorBig1
    this.arcColorBig2 = config.arcColorBig2
    this.arcColorBig3 = config.arcColorBig3
    this.arcColorBig4 = config.arcColorBig4
    this.cPlayColor = config.cPlayColor
    this.arcColorLine = config.arcColorLine
    let can = document.createElement('canvas')
    let dpr = window.devicePixelRatio
    can.style.cssText = `
      width: ${this.width}px;
      height: ${this.height}px;
      position: absolute;
      z-index: 9;
      top: ${config.arcMoveY}px;
      left: 50%;
      transform: translateX(-50%);
    `
    can.width = dpr * this.width
    can.height = dpr * this.height
    config.el.appendChild(can)
    this.can = can
    this.ctx = new Ctx2(can.getContext('2d'), this.width, this.height)
    this.ctx.scale(dpr, dpr)
  }

  init() {
    this.rotate1 = 0

    if (this.timer) clearInterval(this.timer)
    this.timer = setInterval(() => {
      this.rotate1 = this.rotate1 + this.addNum
    }, 1000 / 60)

    this.ctx.onEvent(this.can)
    this.drawTurn()
  }

  stop() {
    if (this.timer) clearInterval(this.timer)
    this.rotate2 = 0
    this.addNum = 1
  }

  remove() {
    this.ctx.remove()
  }

  drawTurn() {
    let _this = this
    let grad = this.ctx.createLinearGradient(this.half, this.half, 100, 100, [
      [0.8, this.arcColorBig2],
      [0, this.arcColorBig1],
    ])
    let grad1 = this.ctx.createLinearGradient(this.half, this.half, 100, 100, [
      [0.8, this.arcColorBig4],
      [0, this.arcColorBig3],
    ])
    let arr1 = [
      {
        attr: [[this.half, this.half, this.half, 0, Math.PI * 2], grad],
        type: this.ctx.arcFill,
        rotate: [this.half, this.half, 180],
        save: true,
        restore: true,
      },
      {
        attr: [[this.half, this.half, this.half * 0.88, 0, Math.PI * 2], grad1],
        type: this.ctx.arcFill,
        rotate: [this.half, this.half, 180],
        save: true,
        restore: true,
      },
    ]

    for (let i = 0; i < this.lightNum; i++) {
      let ww1 = this.half + this.half * 0.935 * Math.cos(((360 / this.lightNum) * i * Math.PI) / 180)
      let wh1 = this.half + this.half * 0.935 * Math.sin(((360 / this.lightNum) * i * Math.PI) / 180)

      arr1.push({
        attr: [[ww1, wh1, this.half * 0.045], '#fff'],
        type: this.ctx.arcFill,
        colorArr: [],
        handle() {
          _this.throttle(() => {
            _this.lightFlag = !_this.lightFlag
          }, 'key1')
          if (_this.lightFlag) {
            this.colorArr = [_this.lightColorOn, _this.lightColorOff]
          } else {
            this.colorArr = [_this.lightColorOff, _this.lightColorOn]
          }
          this.attr[1] = this.colorArr[i % this.colorArr.length]
        },
      })
    }

    arr1.push({
      save: true,
      rotate: [],
      handle() {
        this.rotate = [_this.half, _this.half, _this.rotate1]
      },
    })

    // 礼物转盘动画
    for (var i = 0; i < this.prizeList.length; i++) {
      let rotateNum = parseInt(360 / this.prizeList.length) * i - (90 + 360 / this.prizeList.length / 2)
      let wwhhX = (this.width / 2) * 0.6 * 2 * Math.sin(((360 / this.prizeList.length / 2) * Math.PI) / 180)
      let wwhh = (Math.PI * 2 * this.width) / this.prizeList.length / 7
      if (wwhh > this.half / 3.5) {
        wwhh = this.half / 3.5
      }

      arr1.push({
        attr: [[this.half, this.half, this.half * 0.83, Math.PI * 2, (Math.PI * 2) / this.prizeList.length], this.prizeList[i].bgColor || '#fff'],
        type: this.ctx.arcFill,
        save: true,
        rotate: [this.half, this.half, rotateNum],
      })

      arr1.push({
        attr: [this.prizeList[i].name, this.half * 1.1 + wwhhX / 2, this.height * 0.56, ['#333', '12px bold']],
        type: this.ctx.textFill,
        save: true,
        rotate: [this.half * 1.45, this.half * 1.3, 90 + 180 / this.prizeList.length],
      })

      arr1.push({
        attr: ['', this.half * 1.1 + wwhhX / 2 - wwhh / 2, this.height * 0.59, wwhh, wwhh],
        type: this.ctx.imgFill,
        restore: true,
        arrIndex: i,
        handle() {
          if (!this.attr[0]) {
            _this.ctx
              .loadImg(_this.prizeList[this.arrIndex].img)
              .then((res) => {
                this.attr[0] = res
              })
              .catch(() => {})
          }
        },
      })

      arr1.push({
        restore: true,
      })
    }

    if (this.arcColorLine) {
      for (var i = 0; i < this.prizeList.length; i++) {
        let rotateNum = parseInt(360 / this.prizeList.length) * i - (90 + 360 / this.prizeList.length / 2)
        arr1.push({
          attr: [
            [
              { x: this.half, y: this.half },
              { x: this.half + this.half * 0.88, y: this.half },
            ],
            this.arcColorLine,
            4,
          ],
          type: this.ctx.lineStroke,
          save: true,
          restore: true,
          rotate: [this.half, this.half, rotateNum],
        })
      }
    }

    arr1.push({
      restore: true,
    })

    let arr2 = [
      {
        attr: [
          [
            {
              x: this.half * 0.86,
              y: this.half,
            },
            {
              x: this.half,
              y: this.half,
            },
            {
              x: this.half,
              y: this.half * 0.65,
            },
          ],
          this.arrowColor,
        ],
        save: true,
        restore: true,
        globalAlpha: 0.8,
        type: this.ctx.edgeFill,
      },
      {
        attr: [
          [
            {
              x: this.half * 1.14,
              y: this.half,
            },
            {
              x: this.half,
              y: this.half,
            },
            {
              x: this.half,
              y: this.half * 0.65,
            },
          ],
          this.arrowColor,
        ],
        save: true,
        restore: true,
        globalAlpha: 0.8,
        type: this.ctx.edgeFill,
      },
      {
        attr: [[this.half, this.half, 36], _this.cPlayColor],
        type: this.ctx.arcFill,
        name: 'arcFill',
        click: (attr, ev) => {
          if (attr && attr.name === 'arcFill') {
            _this.vue.turnPlay()
          }
        },
      },
      // {
      //   attr: ['', this.half - 36, this.half - 36, 72, 72],
      //   type: this.ctx.imgArcFill,
      //   handle() {
      //     if (!this.attr[0]) {
      //       _this.ctx
      //         .loadImg(_this.cPlayImg)
      //         .then((res) => {
      //           this.attr[0] = res
      //         })
      //         .catch(() => {})
      //     }
      //   },
      //   name: 'imgFill',
      //   click: (attr, ev) => {
      //     if (attr && attr.name === 'imgFill') {
      //       _this.vue.turnPlay()
      //     }
      //   },
      // },
      {
        attr: [this.btnText, this.half, this.half, ['#fff', '13px bold']],
        type: this.ctx.textFill,
      },
    ]

    this.ctx
      .push(arr1)
      .push(arr2)
      .show()
  }

  playGame1() {
    this.animateNum = 3
    if (this.timer2) clearTimeout(this.timer2)
    this.rotate2 = (360 / this.prizeList.length) * (this.prizeList.length - this.vue.prizeNo) + 360 * 3
    this.animate(this.rotate1 % 360, this.rotate2, 300, (val, end) => {
      if (end) {
        this.vue.alertMsg()
      }
      this.rotate1 = val
    })
  }

  playGame2() {
    this.animateNum = 2
    this.rotate2 = this.rotate2 + 360 * 500000000
    this.animate(this.rotate1 % 360, this.rotate2, 500000000, (val) => {
      this.rotate1 = val
    })
  }

  playGame() {
    this.stop()
    this.animateNum = 1
    this.rotate2 = 360 * 3
    this.animate(this.rotate1 % 360, this.rotate2, 200, (val, end) => {
      if (end) {
        this.playGame2()
      }
      this.rotate1 = val
    })
  }

  animate(start, to, duration = 500, fn) {
    let currentTime = 0
    let val = 0
    let _this = this

    const Tween = {
      Quad: {
        //二次方缓动效果
        easeIn: function(t, b, c, d) {
          return c * (t /= d) * t + b
        },
        easeOut: function(t, b, c, d) {
          return -c * (t /= d) * (t - 2) + b
        },
        easeInOut: function(t, b, c, d) {
          if ((t /= d / 2) < 1) return (c / 2) * t * t + b
          return (-c / 2) * (--t * (t - 2) - 1) + b
        },
      },
    }

    function loop() {
      currentTime += 1
      if (_this.animateNum === 1) {
        val = Tween.Quad.easeIn(currentTime, start, to - start, duration)
      } else if (_this.animateNum === 2) {
        val = val + 10
      } else if (_this.animateNum === 3) {
        val = Tween.Quad.easeOut(currentTime, start, to - start, duration)
      }
      fn(val)
      if (currentTime < duration) {
        _this.timer2 = setTimeout(() => {
          loop()
        }, 1000 / 60)
        // requestAnimationFrame(loop)
      } else {
        fn(val, 'end')
      }
    }
    loop()
  }

  throttle(fn, key, time = 1000) {
    // 节流
    if (!this.timer1[key]) {
      this.timer1[key] = setTimeout(() => {
        clearTimeout(this.timer1[key])
        this.timer1[key] = null
        fn()
        this.throttle(fn, key, time)
      }, time)
    }
  }
}
